/* eslint-disable @typescript-eslint/no-unused-vars */
/**
 * 堆叠柱状图
 */
import React from 'react';
import { Column, ColumnOptions, Bar, BarOptions } from '@antv/g2plot';
// import { message } from 'antd';
import { DL_TYPE, WD_TYPE, THEME_COLOR } from 'src/pages/AnalyseManage/EditReport/components/EditorDataType/EnumConfig';
import { getComponentData } from 'src/services/AnalyseManage';
// transformDataUnitData
import { bigNumberTransform, digitFormat, isNumber } from 'src/libs/utils';
import { ChartService, IProps } from 'src/pages/AnalyseManage/EditReport/components/ChartsType/components/ChartService';
import { CHART_LINK } from 'src/pages/AnalyseManage/EditReport/topics';
import PubSub from 'pubsub-js';

const DEFAULT_DATA = [
	{
		name: '1991',
		value: 9123,
		category: 'Lon',
	},
	{
		name: '1992',
		value: 1231,
		category: 'Lon',
	},
	{
		name: '1993',
		value: 3321.5,
		category: 'Lon',
	},
	{
		name: '1994',
		value: 42145,
		category: 'Lon',
	},
	{
		name: '1995',
		value: 24124.9,
		category: 'Lon',
	},
	{
		name: '1996',
		value: 2126,
		category: 'Lon',
	},
	{
		name: '1997',
		value: 327,
		category: 'Lon',
	},
	{
		name: '1998',
		value: 9123,
		category: 'Lon',
	},
	{
		name: '1999',
		value: 4213,
		category: 'Lon',
	},
	{
		name: '1991',
		value: 3521,
		category: 'Bor',
	},
	{
		name: '1992',
		value: 44124,
		category: 'Bor',
	},
	{
		name: '1993',
		value: 3532.5,
		category: 'Bor',
	},
	{
		name: '1994',
		value: 5342,
		category: 'Bor',
	},
	{
		name: '1995',
		value: 3234.9,
		category: 'Bor',
	},
	{
		name: '1996',
		value: 23436,
		category: 'Bor',
	},
	{
		name: '1997',
		value: 72323,
		category: 'Bor',
	},
	{
		name: '1998',
		value: 3229,
		category: 'Bor',
	},
	{
		name: '1999',
		value: 1333,
		category: 'Bor',
	},
];

export default class StackedColumn extends ChartService {

	state = {
		chartEl: null,
		data: [],
		xField: 'name',
		yField: 'value',
		seriesField: 'category',
		xAlias: 'name',
		yAlias: 'value',
		dataUnit: [],
		eventToken: [],
		dependencies: [],	//	图表联动参数
		isRender: false
	};

	getConfig = (): ColumnOptions | BarOptions => {
		const { config = {} } = this.props;
		const { style = {}, data: dataConfigs = {} } = config;
		const { columnType } = dataConfigs;
		// console.log( style );
		return {
			autoFit: true,
			isStack: true,
			data: this.state.data,
			xField: this.state.xField,
			yField: this.state.yField,
			seriesField: this.state.seriesField,
			theme: { maxColumnWidth: style.columnWidth },
			marginRatio: style.columnMargin,
			appendPadding: [
				style.chartTopPadding || 0,
				style.chartRightPadding || 0,
				style.chartBottomPadding || 0,
				style.chartLeftPadding || 0
			],
			padding: 'auto',
			columnStyle: {
				style: {
					borderRadius: style.columnRadio,
				}
			},
			legend: style.isShowLegend === true ?
				{
					position: style.legendPosition,
					itemName: {
						style: {
							fill: style.legendFontColor || '#333',
							fontSize: parseInt( style.legendFontSize || 15 ),
							fontFamily: style.legendFontFamily,
							fontWeight: style.legendFontBold ? 'bold' : 'normal',
							fontStyle: style.legendFontItalic ? 'italic' : 'normal',
						},
					},
				} : false,
			label: style.isShowLabelData ?
				{
					position: style.chartLabelPosition || 'middle', // 'top', 'bottom', 'middle',
					style: {
						fontFamily: style.labelFontFamily,
						fontSize: parseInt( style.labelFontSize || 15 ),
						fontWeight: style.labelFontBold ? 'bold' : 'normal',
						fontStyle: style.labelFontItalic ? 'italic' : 'normal',
						fill: style.labelFontColor || '#333',
					},
					layout: [
						// 柱形图数据标签位置自动调整
						{ type: 'interval-adjust-position' },
						// 数据标签防遮挡
						{ type: 'interval-hide-overlap' },
						// 数据标签文颜色自动调整
						{ type: 'adjust-color' },
					],
					formatter: ( data ) => {
						let { value, precision = '', dataUnit = '' } = data;
						const valueList = this.state.data.map( t => t.value );
						const maxValue = valueList.reduce( ( acc, cur ) => acc > cur ? acc : cur );
						const minValue = valueList.reduce( ( acc, cur ) => acc > cur ? cur : acc );
						if (
							( style.onlyShowLabelMax && data.value === maxValue ) ||
							( style.onlyShowLabelMin && data.value === minValue ) ||
							( !style.onlyShowLabelMax && !style.onlyShowLabelMin )
						) {
							value = isNumber( precision ) ? value.toFixed( precision ) : value;
							return `${value}${dataUnit}`;
						}
					}
				} : null,
			tooltip: this.getToolTipConfig( style ),
			xAxis: {
				line: style.isShowXLine ? {
					style: {
						stroke: style.chartLineColor,
					}
				} : null,
				title: style.isShowXLineName ?
					{
						style: {
							// offset: 5,
							// textAlign: 'center',
							fontFamily: style.XLineFontFamily,
							fontSize: parseInt( style.XLineFontSize || 15 ),
							fontWeight: style.XLineFontBold ? 'bold' : 'normal',
							fontStyle: style.XLineFontItalic ? 'italic' : 'normal',
							fill: style.XLineFontColor || '#333',
						},
					} : null,
				label: {
					style: style.chartLineDataColor ?
						{
							fill: style.chartLineDataColor,
						} : {},
					formatter( data ) {
						// console.log( columnType, data );
						if ( columnType === 'stackedBar' ) {
							let v = bigNumberTransform( data );
							return `${v}${dataConfigs.yLAxisUnit || ''}`;
						}
						return data;
					}
				},
			},
			yAxis: {
				line: style.isShowYLine ?
					{
						style: {
							stroke: style.chartLineColor,
						},
					} : null,
				title: style.isShowYLineName ?
					{
						style: {
							// offset: 5,
							// textAlign: 'center',
							fontFamily: style.YLineFontFamily,
							fontSize: parseInt( style.YLineFontSize || 15 ),
							fontWeight: style.YLineFontBold ? 'bold' : 'normal',
							fontStyle: style.YLineFontItalic ? 'italic' : 'normal',
							fill: style.YLineFontColor || '#333',
						},
					} : null,
				// 设置坐标轴文字部分样式
				label: {
					style: style.chartLineDataColor ?
						{
							fill: style.chartLineDataColor,
						} : {},
					rotate: style.chartYAxisLabelTilt ? style.chartYAxisLabelTilt : 0,
					formatter( data ) {
						if ( columnType === 'stackedColumn' ) {
							let v = bigNumberTransform( data );
							return `${v}${dataConfigs.yLAxisUnit || ''}`;
						}
						return data;
					}
				},
				// 网格线样式
				grid: style.isHiddenYGridLine ?
					null : {
						line: {
							style: {
								stroke: style.chartGridlineColor,
							},
						},
					}
			},
			meta: {
				name: {
					alias: this.state.xField === 'name' ? style.chartXAxisName || 'name' : style.chartYAxisName || 'value',
				},
				value: {
					alias: this.state.yField === 'value' ? style.chartYAxisName || 'value' : style.chartXAxisName || 'name',
					formatter: ( data ) => {
						return data;
					},
				},
			},
			color: ( style.customBlockColor ? style.customBlockColor.map( ( v ) => v.color ) : [] ).concat( THEME_COLOR ),
		};
	}

	// 设置tooltip
	getToolTipConfig = ( style ) => {
		return style.isShowToolTip
			? {
				// 设置toolTip相关样式
				domStyles: {
					'g2-tooltip-list-item': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor || '#333',
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
					'g2-tooltip-title': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor || '#333',
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
				},
				// showMarkers: true,
				showContent: true,
				follow: true,
				fields: [ 'name', 'value', 'category', 'precision', 'dataUnit' ],
				formatter: ( datum ) => {
					let { category, value, precision = '', dataUnit = '' } = datum;
					value = isNumber( precision ) ? value.toFixed( precision ) : value;		//	小数尾数格式化
					value = digitFormat( value, 3 );				//	千分位格式化

					return {
						name: category,
						value: `${value}${dataUnit}`
					};
				},
			}
			: {
				// showMarkers: false,
				showContent: false,
				domStyles: null,
				follow: false,
			};
	};

	// 入参构建
	itemInfo = ( v ) => {
		return {
			aggregateType: v.modelType === DL_TYPE ? v.aggregateType : '', //	度量的聚合类型
			formatType: v.modelType === WD_TYPE ? v.formatType : '', // 维度的聚合类型v.
			alias: v.title.trim(),
			dataType: v.dataType,
			frontendId: '',
			id: v.name,
			orderType: v.orderType, // 排序方式
			quota: v.modelType === WD_TYPE ? 'WD' : 'DL',
			symbol: '',
			type: v.type,
			value: '',
			dataUnit: v.dataUnit || '',
			precision: v.precision
		};
	};

	async getConditionData() {
		const { config = {} } = this.props;
		const { xAxis = [], yLAxis = [], series = [] } = config.data;
		// console.log( config );
		if ( xAxis.length && yLAxis.length ) {
			const x = xAxis.map( v => this.itemInfo( v ) );
			const y = yLAxis.map( v => this.itemInfo( v ) );
			const category = series.map( v => this.itemInfo( v ) );
			// const conditions = this.props.config.data.filterFields ? this.props.config.data.filterFields.map( v => v.filterConditions ).flat() : [];
			
			// 内部筛选 condition
			const filterFieldCondition = this.props.config.data.filterFields
				? this.props.config.data.filterFields.map( ( v ) => v.filterConditions ).flat()
				: [];

			// 筛选组件的 condition
			let filterCompConditions = this.props.config.data.filterConditions || {};
			let newFilterCompConditions = [];
			Object.keys( filterCompConditions ).forEach( ( key ) => {
				newFilterCompConditions = newFilterCompConditions.concat( filterCompConditions[key] );
			} );

			const request = {
				dataConfig: {
					dataModel: {
						pageId: this.props.pageId,
						tableName: config.data.tableCode,
						x,
						y,
						category,
						conditions: filterFieldCondition.concat( this.state.dependencies, newFilterCompConditions )
					},
					needAutoRefresh: true,
					tableType: 'stack'
				},
				type: 'column',
				tenantCode: this.props.tenantCode
			};
			let pageResponse = await getComponentData( request );
			if ( pageResponse.data ) {
				let { rows = [], extra } = pageResponse.data.data || {};
				if ( pageResponse.data.success && rows && rows.length > 0 ) {
					// const newRows = transformDataUnitData( rows, y, 'value' );

					return { rows, dataUnit: ( extra && extra.dataUnit ) || [] };
				}
			}
		}
		return { rows: DEFAULT_DATA, dataUnit: [] };
	}

	changeChartType = ( type ) => {
		let chart = null;
		let xField = null;
		let yField = null;
		if ( type === 'stackedColumn' ) {
			xField = 'name';
			yField = 'value';
			chart = new Column( this.props.id, this.getConfig() );
			this.props.onValuesChange(
				this.props.config.type,
				this.props.id,
				{
					titleValue: '堆叠柱状图',
				},
				'style'
			);
		} else if ( type === 'stackedBar' ) {
			xField = 'value';
			yField = 'name';
			chart = new Bar( this.props.id, this.getConfig() );
			this.props.onValuesChange(
				this.props.config.type,
				this.props.id,
				{
					titleValue: '堆叠条形图',
				},
				'style'
			);
		}
		if ( chart ) {
			this.setState( {
				xField,
				yField
			}, () => {
				this.state.chartEl.destroy();
				chart.update( this.getConfig() );
				this.setState( {
					chartEl: chart
				} );
			} );
		}
	}

	shouldComponentUpdate( nextProps: Readonly<IProps>, nextState: Readonly<{ dependencies: any }>, nextContext: any ): boolean {
		if ( JSON.stringify( nextProps ) !== JSON.stringify( this.props ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( nextState.dependencies ) ) return true;
		return false;
	}

	getSnapshotBeforeUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{ dependencies: any }> ): any | null {
		let { config, chartLayout } = this.props;
		let changeObj = Object.create( null );
		const { xAxis = [], yLAxis = [], series = [], columnType, filterFields = [] } = config.data || {};
		const { xAxis: pxAxis = [], yLAxis: pyLAxis = [], series: pSeries = [], 
			columnType: pColumnType, filterFields: pfilterFields = [] } = prevProps.config.data || {};

		//	判断图表类型/数据字段是否变化了
		if ( config.data.tableCode === prevProps.config.data.tableCode && columnType !== pColumnType ) {
			changeObj.needChartTypeChange = true;
		} else if ( ( xAxis.length && yLAxis.length ) &&
			( JSON.stringify( pxAxis ) !== JSON.stringify( xAxis ) ||
				JSON.stringify( pyLAxis ) !== JSON.stringify( yLAxis ) ||
				JSON.stringify( pSeries ) !== JSON.stringify( series ) ||
				JSON.stringify( pfilterFields ) !== JSON.stringify( filterFields ) ||
				JSON.stringify( this.state.dependencies ) !== JSON.stringify( prevState.dependencies ) ||
				JSON.stringify( prevProps.config.data.filterConditions ) !== JSON.stringify( config.data.filterConditions ) ) ) {
			changeObj.needDataChange = true;
		}

		//	判断样式是否改变
		if ( JSON.stringify( prevProps.config.data.yLAxisUnit ) !== JSON.stringify( config.data.yLAxisUnit ) ||
		    JSON.stringify( prevProps.config.style ) !== JSON.stringify( config.style ) ) {
			changeObj.needStyleChange = true;
		}

		//判断是否因宽高改变重新适应布局
		if ( prevProps.chartLayout.w !== chartLayout.w || prevProps.chartLayout.h !== chartLayout.h ) {
			changeObj.needLayoutChange = true;
		}
		console.log( changeObj );
		return changeObj;
	}

	initEvent = async () => {
		const { dataUnit = [], rows = [] } = await this.getConditionData();
		console.log( rows );
		const { xAxis = [], yLAxis = [], columnType = 'stackedColumn' } = this.props.config.data;
		const xAlias = xAxis.map( t => t.title ).join( '-' ) || 'name';
		const yAlias = yLAxis.map( t => t.title ).join( '-' ) || 'value';
		// console.log( columnType, this.props.config.data );
		let chart = null;
		let xField = null;
		let yField = null;
		if ( columnType === 'stackedColumn' ) {
			xField = 'name';
			yField = 'value';
		} else {
			xField = 'value';
			yField = 'name';
		}
		this.setState( {
			data: rows,
			xAlias,
			yAlias,
			xField,
			yField,
			dataUnit: dataUnit
		}, () => {
			if ( columnType === 'stackedColumn' ) {
				chart = new Column( this.props.id, this.getConfig() );
			} else if ( columnType === 'stackedBar' ) {
				chart = new Bar( this.props.id, this.getConfig() );
			}
			chart.render();
			this.setState( {
				chartEl: chart,
				isRender: true
			} );

			//	数据联动 组装联动参数
			chart.on( 'element:click', ( ev ) => {
				if( !this.props.config.mutual.isChainAvailable ) return;

				const intervalElement = ev.target.get( 'element' );
				const data = intervalElement.getModel().data; // 单条数据
				console.log( data );

				let dependencies = [];
				const xAxis = this.props.config.data.xAxis || [];
				if( xAxis.length > 0 ) {
					dependencies = dependencies.concat( xAxis.map( ( item, index ) => {
						return {
							formatType: item.formatType,
							id: [ item.name ],
							quota: item.modelType === WD_TYPE ? 'WD' : 'DL',
							symbol: 'EQ',
							value: [ data.name ]		//	从原数据中找到item，一一对应字段
						};
					} ) );
				}

				const series = this.props.config.data.series || [];
				if( series.length > 0 ) {
					dependencies = dependencies.concat( series.map( ( item, index ) => {
						return {
							formatType: item.formatType,
							id: [ item.name ],
							quota: item.modelType === WD_TYPE ? 'WD' : 'DL',
							symbol: 'EQ',
							value: [ data.category ]		//	从原数据中找到item，一一对应字段
						};
					} ) );
				}

				if( dependencies.length === 0 ) return;

				PubSub.publish( CHART_LINK, {
					publisherId: this.props.id,
					listenerIds: this.props.config.mutual.chartsChainIds,
					dimension: dependencies,
					tableCode: this.props.config.data.tableCode
				} );
			} );
		} );
	};

	async componentDidUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{}>, snapshot?: any ) {
		// console.log( 'column', snapshot );

		const { columnType } = this.props.config.data || {};
		if ( snapshot.needStyleChange ) this.state.chartEl.update( this.getConfig() );

		if ( snapshot.needChartTypeChange ) this.changeChartType( columnType );

		if ( snapshot.needDataChange ) {
			// console.log( this.state.data );
			const { xAxis = [], yLAxis = [] } = this.props.config.data;
			const xAlias = xAxis.map( t => t.title ).join( '-' ) || 'name';
			const yAlias = yLAxis.map( t => t.title ).join( '-' ) || 'value';
			const resData = await this.getConditionData();
			const { dataUnit, rows } = await this.getConditionData();

			this.setState( {
				data: rows,
				xAlias,
				dataUnit,
				yAlias
			}, () => {
				this.state.chartEl.changeData( this.state.data );
			} );
		}
	}

	render() {
		return <div id={this.props.id} style={{ height: '100%' }}></div>;
	}
};
